"""
能力管理组件
负责LLM提供商能力的注册、查询和执行
"""
from typing import Dict, Any, Type, Optional, Set, List, TypeVar, Callable
import logging

# 设置日志
logger = logging.getLogger("connllm.capability")

# 泛型类型变量，用于表示能力类型
C = TypeVar('C')

class CapabilityManager:
	"""能力管理器，负责能力的注册和访问"""
	
	def __init__(self, provider: Any):
		"""
		初始化能力管理器
		
		Args:
			provider: 所属提供商实例
		"""
		self.provider = provider
		self.capabilities: Dict[str, Any] = {}
		
	def register(self, capability_id: str, implementation_class: Type) -> None:
		"""
		注册能力
		
		Args:
			capability_id: 能力ID
			implementation_class: 能力实现类
		"""
		try:
			# 创建能力实例
			capability = implementation_class(self.provider)
			
			# 检查能力是否支持当前提供商和模型
			if capability.is_supported():
				self.capabilities[capability_id] = capability
				logger.debug(f"已注册能力: {capability_id}")
				
				# 处理依赖
				self._register_dependencies(capability_id, implementation_class)
			else:
				logger.debug(f"能力 {capability_id} 不支持当前提供商/模型配置，跳过注册")
				
		except Exception as e:
			# 记录错误但不中断流程
			logger.warning(f"注册能力 {capability_id} 失败: {str(e)}")
	
	def _register_dependencies(self, capability_id: str, implementation_class: Type) -> None:
		"""
		注册能力依赖
		
		Args:
			capability_id: 能力ID
			implementation_class: 能力实现类
		"""
		# 从实现类获取依赖信息
		dependencies = getattr(implementation_class, 'dependencies', set())
		if not dependencies:
			# 尝试调用get_dependencies静态方法（兼容旧接口）
			if hasattr(implementation_class, 'get_dependencies'):
				dependencies = implementation_class.get_dependencies()
			else:
				dependencies = set()
		
		# 如果没有依赖，直接返回
		if not dependencies:
			return
			
		logger.debug(f"能力 {capability_id} 依赖: {dependencies}")
		
		# 从能力注册表获取依赖实现
		try:
			from ..capabilities import get_registered_capability
			
			for dep_id in dependencies:
				if dep_id not in self.capabilities:
					dep_class = get_registered_capability(dep_id)
					if dep_class:
						self.register(dep_id, dep_class)
					else:
						logger.warning(f"能力 {capability_id} 依赖未注册的能力: {dep_id}")
		except ImportError:
			logger.warning(f"无法导入get_registered_capability函数，无法注册依赖")
	
	def has(self, capability_id: str) -> bool:
		"""
		检查是否有指定能力
		
		Args:
			capability_id: 能力ID
			
		Returns:
			是否支持
		"""
		return capability_id in self.capabilities
		
	def get(self, capability_id: str) -> Any:
		"""
		获取能力实例
		
		Args:
			capability_id: 能力ID
			
		Returns:
			能力实例
			
		Raises:
			UnsupportedOperationError: 如果不支持该能力
		"""
		if not self.has(capability_id):
			# 尝试使用标准异常
			try:
				from ..core.exceptions import UnsupportedOperationError
				provider_type = getattr(self.provider, 'provider_type', 'unknown')
				model = getattr(self.provider, 'model', 'unknown')
				raise UnsupportedOperationError(f"不支持能力: {capability_id}", provider_type, model)
			except ImportError:
				# 如果无法导入，使用通用RuntimeError
				raise RuntimeError(f"不支持能力: {capability_id}")
				
		return self.capabilities[capability_id]
		
	def get_safely(self, capability_id: str) -> Optional[Any]:
		"""
		安全获取能力实例，不存在时返回None
		
		Args:
			capability_id: 能力ID
			
		Returns:
			能力实例或None
		"""
		return self.capabilities.get(capability_id)
		
	def get_all(self) -> Dict[str, Any]:
		"""
		获取所有能力实例
		
		Returns:
			能力字典
		"""
		return self.capabilities.copy()
		
	def get_capability_ids(self) -> Set[str]:
		"""
		获取所有能力ID
		
		Returns:
			能力ID集合
		"""
		return set(self.capabilities.keys())
		
	def execute(self, capability_id: str, method_name: str, *args, **kwargs) -> Any:
		"""
		执行能力方法
		
		Args:
			capability_id: 能力ID
			method_name: 方法名
			*args: 位置参数
			**kwargs: 关键字参数
			
		Returns:
			方法执行结果
			
		Raises:
			UnsupportedOperationError: 如果不支持该能力
			AttributeError: 如果能力不支持该方法
		"""
		capability = self.get(capability_id)
		
		if not hasattr(capability, method_name):
			raise AttributeError(f"能力 {capability_id} 不支持方法 {method_name}")
			
		method = getattr(capability, method_name)
		return method(*args, **kwargs)
		
	def execute_safely(self, capability_id: str, method_name: str, 
					   default: Any = None, *args, **kwargs) -> Any:
		"""
		安全执行能力方法，出错时返回默认值
		
		Args:
			capability_id: 能力ID
			method_name: 方法名
			default: 默认返回值
			*args: 位置参数
			**kwargs: 关键字参数
			
		Returns:
			方法执行结果或默认值
		"""
		try:
			return self.execute(capability_id, method_name, *args, **kwargs)
		except Exception as e:
			logger.warning(f"执行能力 {capability_id}.{method_name} 失败: {str(e)}")
			return default
	
	def clear(self) -> None:
		"""清除所有注册的能力"""
		self.capabilities.clear()
